package com.cjw.service.impl.soulread;

import com.cjw.enums.share.SharingType;
import com.cjw.mapper.database.MinioFileMapper;
import com.cjw.mapper.database.UserMapper;
import com.cjw.mapper.person.UserDetailMapper;
import com.cjw.mapper.soulread.ReadMapper;
import com.cjw.mapper.soulread.ReadMinioMapper;
import com.cjw.mapper.soulread.ReadUserMapper;
import com.cjw.pojo.dto.database.PageDTO;
import com.cjw.pojo.dto.database.UserDTO;
import com.cjw.pojo.dto.soulread.DetailReadDTO;
import com.cjw.pojo.dto.soulread.ReadDTO;
import com.cjw.pojo.dto.soulread.RecommendReadDTO;
import com.cjw.pojo.entity.database.MinioFile;
import com.cjw.pojo.entity.person.UserDetail;
import com.cjw.pojo.entity.soulread.Read;
import com.cjw.pojo.entity.soulread.ReadMinio;
import com.cjw.pojo.entity.soulread.ReadUser;
import com.cjw.service.soulread.HeatService;
import com.cjw.service.soulread.ReadService;
import com.cjw.service.soulread.TagService;
import com.cjw.util.BaseContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @create_time : 2021.12.30
 * @author : cjw
 */
@Service("readService")
public class ReadServiceImpl implements ReadService {
    @Autowired
    private UserDetailMapper userDetailMapper;

    @Autowired
    private ReadMapper readMapper;

    @Autowired
    private ReadUserMapper readUserMapper;

    private String heat = "heat";

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private HeatService heatService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TagService tagService;

    @Autowired
    private ReadMinioMapper readMinioMapper;

    @Autowired
    private MinioFileMapper minioFileMapper;

    @Override
    public PageDTO<List<ReadDTO>> findAllRead(Integer page, Integer size, String find, Long tagId) {
        ArrayList<ReadDTO> readDTOS = new ArrayList<>();
        for (Read read : readMapper.findAll(page*size, size, find, tagId)) {
            ReadDTO readDTO = new ReadDTO();
            readDTO.setAddTime(read.getAddTime());
            readDTO.setId(read.getId());
            readDTO.setTopic(read.getTopic());
            readDTO.setHeat(heatService.getHeat(read.getId()).intValue());
            readDTO.setPicture(read.getPicture());
            readDTO.setCollection(isCollectionOrLove(read.getId(), SharingType.COLLECTION.getCode()));
            readDTOS.add(readDTO);
        }
        PageDTO<List<ReadDTO>> readDTOS1 = new PageDTO<>();
        readDTOS1.setDtos(readDTOS);
        readDTOS1.setTotal(readMapper.findAllTotal(find,tagId));
        return readDTOS1;
    }

    @Override
    public DetailReadDTO findDetailRead(Long readId) {
        Read read = new Read();
        read.setId(readId);
        read.setIsPublic(1);
        Read read1 = readMapper.selectOne(read);
        if (read1 == null)
            return null;

        DetailReadDTO detailReadDTO = new DetailReadDTO();
        detailReadDTO.setTagDTOList(tagService.getTagDTOByReadId(readId));
        UserDTO user = (UserDTO) BaseContextHolder.get("user");
        detailReadDTO.setReadName(user.getUserName());
        UserDetail userDetail = new UserDetail();
        userDetail.setUserId(read1.getUserId());
        detailReadDTO.setReadHeadImage(userDetailMapper.selectOne(userDetail).getHeadImage());
        detailReadDTO.setContent(read1.getContent());
        detailReadDTO.setReadImage(read1.getPicture());
        detailReadDTO.setReadUrl(getUrl(readId));
        detailReadDTO.setLove(isCollectionOrLove(readId, SharingType.LOVE.getCode()));
        detailReadDTO.setCollection(isCollectionOrLove(readId, SharingType.COLLECTION.getCode()));
        return detailReadDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean loveCollection(Long readId, Integer type) {
        UserDTO user = (UserDTO) BaseContextHolder.get("user");
        ReadUser readUser = new ReadUser();
        readUser.setUserId(user.getId());
        readUser.setReadId(readId);
        readUser.setType(type);
        if (isCollectionOrLove(readId, type)) {
            return readUserMapper.delete(readUser) != 0;
        } else {
            readUser.setAddTime(new Date());
            readUser.setUpdateTime(new Date());
            return readUserMapper.insert(readUser) != 0;
        }
    }

    @Override
    public List<RecommendReadDTO> lastHeat() {
        ArrayList<RecommendReadDTO> recommendReadDTOS = new ArrayList<>();
        Set set = redisTemplate.opsForZSet().reverseRange(heat, 0, -1);
        for (Object id : set) {
            Read read = readMapper.selectByPrimaryKey(id);
            RecommendReadDTO recommendReadDTO = new RecommendReadDTO();
            recommendReadDTO.setHeat(read.getScore().intValue());
            recommendReadDTO.setReadId(read.getId());
            recommendReadDTO.setTitle(read.getTopic());
            recommendReadDTO.setUserName(userMapper.selectByPrimaryKey(read.getUserId()).getUserName());
            recommendReadDTO.setPunishTime(read.getAddTime());
            recommendReadDTOS.add(recommendReadDTO);
        }
        return recommendReadDTOS;
    }

    /**
     * 是否收藏/点赞
     * @param readId
     * @return
     */
    private Boolean isCollectionOrLove(Long readId, Integer type) {
        UserDTO user = (UserDTO) BaseContextHolder.get("user");
        ReadUser readUser = new ReadUser();
        readUser.setReadId(readId);
        readUser.setUserId(user.getId());
        readUser.setType(type);
        return readUserMapper.selectOne(readUser) != null;
    }

    /**
     * 获取朗读的音频
     * @param readId
     * @return
     */
    private String getUrl(Long readId) {
        ReadMinio readMinio = new ReadMinio();
        readMinio.setReadId(readId);
        MinioFile minioFile = new MinioFile();
        ReadMinio readMinio1 = readMinioMapper.selectOne(readMinio);
        if (readMinio1 == null)
            return null;
        minioFile.setId(readMinio1.getOssId());
        return minioFileMapper.selectOne(minioFile).getUrl();
    }

}
